1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.model
import android.content.ContentProvider
import android.content.ContentValues
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.net.Uri
import org.yuzu.yuzu_emu.BuildConfig
import org.yuzu.yuzu_emu.utils.Log
/**
* Provides an interface allowing Activities to interact with the SQLite database.
* CRUD methods in this class can be called by Activities using getContentResolver().
*/
class GameProvider : ContentProvider() {
private var mDbHelper: GameDatabase? = null
override fun onCreate(): Boolean {
Log.info("[GameProvider] Creating Content Provider...")
mDbHelper = GameDatabase(context!!)
return true
}
override fun query(
uri: Uri,
projection: Array<String>?,
selection: String?,
selectionArgs: Array<String>?,
sortOrder: String?
): Cursor? {
Log.info("[GameProvider] Querying URI: $uri")
val db = mDbHelper!!.readableDatabase
val table = uri.lastPathSegment
if (table == null) {
Log.error("[GameProvider] Badly formatted URI: $uri")
return null
}
val cursor = db.query(table, projection, selection, selectionArgs, null, null, sortOrder)
cursor.setNotificationUri(context!!.contentResolver, uri)
return cursor
}
override fun getType(uri: Uri): String? {
Log.verbose("[GameProvider] Getting MIME type for URI: $uri")
val lastSegment = uri.lastPathSegment
if (lastSegment == null) {
Log.error("[GameProvider] Badly formatted URI: $uri")
return null
}
if (lastSegment == GameDatabase.TABLE_NAME_FOLDERS) {
return MIME_TYPE_FOLDER
} else if (lastSegment == GameDatabase.TABLE_NAME_GAMES) {
return MIME_TYPE_GAME
}
Log.error("[GameProvider] Unknown MIME type for URI: $uri")
return null
}
override fun insert(uri: Uri, values: ContentValues?): Uri {
var realUri = uri
Log.info("[GameProvider] Inserting row at URI: $realUri")
val database = mDbHelper!!.writableDatabase
val table = realUri.lastPathSegment
if (table != null) {
if (table == RESET_LIBRARY) {
mDbHelper!!.resetDatabase(database)
return realUri
}
if (table == REFRESH_LIBRARY) {
Log.info(
"[GameProvider] URI specified table REFRESH_LIBRARY. No insertion necessary; refreshing library contents..."
)
mDbHelper!!.scanLibrary(database)
return realUri
}
val id =
database.insertWithOnConflict(table, null, values, SQLiteDatabase.CONFLICT_IGNORE)
// If insertion was successful...
if (id > 0) {
// If we just added a folder, add its contents to the game list.
if (table == GameDatabase.TABLE_NAME_FOLDERS) {
mDbHelper!!.scanLibrary(database)
}
// Notify the UI that its contents should be refreshed.
context!!.contentResolver.notifyChange(realUri, null)
realUri = Uri.withAppendedPath(realUri, id.toString())
} else {
Log.error("[GameProvider] Row already exists: $realUri id: $id")
}
} else {
Log.error("[GameProvider] Badly formatted URI: $realUri")
}
database.close()
return realUri
}
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
Log.error("[GameProvider] Delete operations unsupported. URI: $uri")
return 0
}
override fun update(
uri: Uri, values: ContentValues?, selection: String?,
selectionArgs: Array<String>?
): Int {
Log.error("[GameProvider] Update operations unsupported. URI: $uri")
return 0
}
companion object {
const val REFRESH_LIBRARY = "refresh"
const val RESET_LIBRARY = "reset"
private const val AUTHORITY = "content://${BuildConfig.APPLICATION_ID}.provider"
@JvmField
val URI_FOLDER: Uri = Uri.parse("$AUTHORITY/${GameDatabase.TABLE_NAME_FOLDERS}/")
@JvmField
val URI_REFRESH: Uri = Uri.parse("$AUTHORITY/$REFRESH_LIBRARY/")
@JvmField
val URI_RESET: Uri = Uri.parse("$AUTHORITY/$RESET_LIBRARY/")
const val MIME_TYPE_FOLDER = "vnd.android.cursor.item/vnd.yuzu.folder"
const val MIME_TYPE_GAME = "vnd.android.cursor.item/vnd.yuzu.game"
}
}
|